home *** CD-ROM | disk | FTP | other *** search
- {***************************************************
- DESCRIPTION
- ===========
- This component allows a system with a Monochrome
- display attached as an alternate monitor to be used
- as a 25x70 event display and a 25x10 status area
- display.
-
- The event messages are upto 70 byte text messages that
- are written to the screen and then followed by the
- upo-arrow line to mark the most current line.
-
- So that multiple pgms can write to the screen
- the up-arrow line is searched for to locate the most
- current line. If the up-arrow line is not found the
- screen is cleared (it is assumed to be first time).
-
- The status messages begin with a 3 byte prefix.
- !nn
- where nn is a value between 0 and 24 (always 2 digits).
- It specifies the row number where the max 10 byte
- msg is written in cols 71 thru 80.
-
- INSTALLATION
- ============
- To install the control, copy the debmono.* files to a directory
- on your Delphi library path and select the
-
- Options | Install Component
-
- menu item.
-
- USAGE
- =====
-
- (1) As a component.
- -------------------
-
- The component is added to a form. I suggest renaming
- it to something short like DM so that the keystrokes are
- reduced.
-
- Then statements such as:
-
- DM.Text := Format('I=%d N=%.4x',[I,n]);
-
- will write a message to the mono screen without
- disturbing at all the windows environment (like
- changing window focus).
-
- The statement
-
- DM.Text := Format('!01I=%d',[I]);
-
- will replace the status line entry at line 1 of
- the status area with a display of the current
- value of I.
-
- Setting the property NoDisplay to non-zero will cause the
- message writing to be completely bypassed. It can be used
- to deactivate debug messages in production mode. Note that
- the overhead of creating the message still exists - only
- the displaying of it is bypassed. I have not found a
- convenient way in Pascal to turn off code like in C. Thats
- the price for 300,000 lines of code compiled per miniute.
-
- (2) As a function.
- ------------------
-
- Sometimes it is not convenient to create other objects
- (such as inside a component) so the MonoText function
- can be called directly. It will have the same effect
- as setting a value to DM.Text (except that the test
- for NoDisplay) is bypassed. eg.
-
- MonoText('This will display');
- MonoText(Format('!05Ctr:%.4d',[ctr]));
-
- ASIDE
- =====
- I discovered the Format function which is barely
- mentioned in the many Delphi books I have purchased
- and which does not exist in Turbo Pascal. The Format
- function is a concise way to create messages to
- send to the screen. It is similar to printf, so with my
- strong backgound in C I felt right at home.
-
- HARDWARE
- ========
- A monochrome display can be attached to a system for
- around $50 ($15 card, $35 used display). It becomes
- a non-obtrusive debugging tool that can be used to
- report code paths with variables (event messages)
- or to monitor variable values (status messages).
-
- Note that under some memory manager systems it is
- necessary to use the switch
- DualDisplay=True
- in the [386enh] section of the SYSTEM.INI file.
-
- COPYRIGHTS
- ==========
- (c) S.Pritchard at Rexcel Systems Inc. 1995.
-
- This small piece of code is a contribution to the
- growing collection of free but useful Delphi
- components. It may be freely used in whatever way
- you choose provided the original source is
- acknowledged.
-
- For suggestions, improvements, comments please email
- to:
- spritchard@rexcel.com (preferred)
- or
- Compuserve 71221,1607 (Steve Pritchard.)
- ****************************************************}
-
- unit Debmono;
-
- interface
-
- uses
- Classes;
-
- type
- TDebMono = class(TComponent)
- private
- { Private declarations }
- FNoDisplay: Word; { True if no display }
- procedure SetText(Text: string);
- function GetText: string;
- protected
- { Protected declarations }
- public
- { Public declarations }
- published
- { Published declarations }
- Property Text: string read GetText write SetText;
- Property NoDisplay: Word read FNoDisplay write FNoDisplay;
- end;
-
- procedure Register;
- procedure MonoAddr;
- procedure MonoText(Text: string);
-
- implementation
-
- procedure MonoAddr; external 'KERNEL' index 181;
-
- procedure Register;
- begin
- RegisterComponents('srp', [TDebMono]);
- end;
- {**************************************
- Although we do not need this it seems to
- avoid a GPF when we try to use the
- component.
- ***************************************}
- function TDebMono.GetText: string;
- begin
- GetText := '---DebMono V1.00 instantiated---';
- end;
-
- procedure TDebMono.SetText(Text: string);
- begin
- if (NoDisplay = 0) then MonoText(Text);
- end;
-
- {**************************************
- Whenever called we copy Text to
- the mono display.
-
- If the string starts with !nn then we
- treat it as a status fld and copy the
- remaining string to the status area.
- **************************************}
- procedure MonoText(Text: string);
- var
- pScrn: ^byte;
- pScrnW: ^word;
- pSeg: Word;
- n,n2,nAt,nRow,nStop,nGo,nFlag: word;
- begin
-
- pSeg := Word(Addr(MonoAddr));
- pScrn := Ptr(pSeg,0);
-
- {locate the up arrows}
- nAt := $FFFF;
- for n := 0 to 24 do begin;
- pScrn := Ptr(pSeg,n*160);
- if (pScrn^ = $18) then begin;
- nAt := n;
- break;
- end;
- end;
-
- {if not found clear the screen}
- if (nAt = $FFFF) then begin;
- for n := 0 to 24 do begin;
- for n2 := 0 to 79 do begin;
- pScrnW := Ptr(pSeg,n*160 + n2*2);
- pScrnW^ := $07FA;
- end;
- end;
- nAt := 0;
- end;
-
- {Set up depending on event | status msg}
- nStop := 70; nGo := 1; {assume event}
- nFlag := $7000;
- pScrnW := Ptr(pSeg,nAt*160);
- if (Text[1] = '!') then begin; {then status}
- nRow := ((Byte(Text[2]) and $0F) * 10) +
- (Byte(Text[3]) and $0F);
- if (nRow > 24) then nRow := 24;
- nStop := 13; nGo := 4;
- pScrnW := Ptr(pSeg,nRow*160 + 70*2);
- nFlag := $0700;
- end;
-
- {Copy message to the screen}
- for n := nGo to nStop do begin;
- if (n <= length(Text)) then
- n2 := nFlag + Byte(Text[n])
- else
- n2 := nFlag + $20;
- pScrnW^ := n2;
- Longint(pScrnW) := Longint(pScrnW) + 2;
- end;
-
- {Add the new up arrows - if event msg (not status msg)}
- if (nFlag = $7000) then begin;
- Inc(nAt);
- if (nAt > 24) then nAt := 0;
- pScrnW := Ptr(pSeg,nAt*160);
- for n := 1 to 70 do begin;
- if (n <= 20) then
- n2 := $0718
- else
- n2 := $0720;
- pScrnW^ := n2;
- Longint(pScrnW) := Longint(pScrnW) + 2;
- end;
- end;
- end;
- end.
-